package main

import (
	"encoding/json"
	"fmt"
	"gitee.com/sqxwww/pprof_heap/guid"
	_ "github.com/google/pprof/driver"
	"github.com/google/pprof/profile"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"time"
	_ "unsafe"
)

type Config struct {
	Url      string `json:"url"`
	Min      int64  `json:"min"`
	Interval int    `json:"interval"`
}

var config Config

var gid *guid.Guid

func init() {
	f, err := os.Open("conf.json")
	if err != nil {
		panic(err)
	}
	defer f.Close()
	de := json.NewDecoder(f)
	de.Decode(&config)
	gid = guid.NewGuid(1)
}

func main() {
	c := http.DefaultClient
	ticker := time.NewTicker(time.Duration(config.Interval) * time.Second)
	for {
		select {
		case <-ticker.C:
			fetchHeap(c)
		}
	}
}

func fetchHeap(c *http.Client) {
	resp, err := c.Get(config.Url + "/heap")
	if err != nil {
		log.Println(err)
		return
	}
	defer resp.Body.Close()
	data, _ := ioutil.ReadAll(resp.Body)
	p, err := profile.ParseData(data)
	if err != nil {
		log.Println(err)
		return
	}
	total := computeTotal(p, valueExtractor(p), nil)
	if total >= config.Min*1024*1024 {
		log.Println(total)
		ioutil.WriteFile(fmt.Sprintf("size(%dKB)_%d", total/1024, gid.NewID()), data, 0666)
	}
}

func valueExtractor(p *profile.Profile) func(v []int64) int64 {
	ix, _ := p.SampleIndexByName("")
	return func(v []int64) int64 {
		return v[ix]
	}
}

//go:linkname computeTotal github.com/google/pprof/internal/report.computeTotal
func computeTotal(prof *profile.Profile, value, meanDiv func(v []int64) int64) int64
